/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.braveo.dict.db.jaxb;

import com.braveo.common.BraveException;
import com.braveo.dict.db.BraveDictEntryDao;
import com.braveo.tools.db.jaxb.BraveDict;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 *
 * @author jeff.huang
 */
public class BraveDictEntryDaoImpl implements BraveDictEntryDao {
    private final String dbName;
    private final String dbHome;
    private final String dbFilePath;
    private BraveDict braveDict;

    private JAXBContext ctx;
    private Unmarshaller unm;
    private Marshaller m;

    public BraveDictEntryDaoImpl(File file){
        dbHome = file.getParent();
        String fileName = file.getName();
        int pos = fileName.lastIndexOf(".");
        if(pos == -1)
            dbName = fileName;
        else
            dbName = fileName.substring(0, pos);
        dbFilePath = file.getAbsolutePath();

        try{
            ctx = JAXBContext.newInstance("com.braveo.tools.db.jaxb");
            unm = ctx.createUnmarshaller();
            m = ctx.createMarshaller();
            m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        }catch(JAXBException e){
            throw new BraveException(e);
        }
    }

    public BraveDictEntryDaoImpl(String dbHome, String dbName){
        this(new File(dbName2XmlFileName(dbHome, dbName)));
    }

    private static String dbName2XmlFileName(String dbHome, String dbName){
        if(dbHome == null || dbHome.length() == 0)
            dbHome = ".";
        if(!dbName.endsWith(".xml"))
            dbName = dbName + ".xml";
        return dbHome + File.separator + dbName + ".xml";
    }

    public void loadFromDatabase() {
        File file = new File(dbFilePath);
        if(!file.exists())
            braveDict = new BraveDict();
        else {
            try{
                braveDict = (BraveDict)unm.unmarshal(file);
            }catch(JAXBException e){
                throw new BraveException(e);
            }
        }
    }

    public void saveToDatabase() {
        if(braveDict == null)
            return;
        
        File file = new File(dbFilePath);
        if(!file.exists()){
            File dir = file.getParentFile();
            if(!dir.exists())
                dir.mkdirs();
        }
        try{
            m.marshal(braveDict, file);
        }catch(JAXBException e){
            throw new BraveException(e);
        }

    }
    
    public void addDictEntry(String key, String explain) {
        loadFromDatabase();
        BraveDict.DictEntry de = new BraveDict.DictEntry();
        de.setDictKey(key);
        de.setDictValue(explain);
        braveDict.getDictEntry().add(de);
        saveToDatabase();
    }

    public boolean updateDictEntry(String key, String explain) {
        loadFromDatabase();
        List<BraveDict.DictEntry> entries = braveDict.getDictEntry();
        for(BraveDict.DictEntry e : entries){
            if(e.getDictKey().equals(key)){
                e.setDictValue(explain);
                saveToDatabase();
                return true;
            }
        }
        return false;
    }

    public boolean deleteDictEntry(String key) {
        loadFromDatabase();
        List<BraveDict.DictEntry> entries = braveDict.getDictEntry();
        for(int k=0; k<entries.size(); ++k){
            if(entries.get(k).getDictKey().equals(key)){
                entries.remove(k);
                saveToDatabase();
                return true;
            }
        }
        return false;
    }

    public String getExplain(String key) {
        loadFromDatabase();
        List<BraveDict.DictEntry> entries = braveDict.getDictEntry();
        for(int k=0; k<entries.size(); ++k){
            BraveDict.DictEntry e = entries.get(k);
            if(entries.get(k).getDictKey().equals(key)){
                return e.getDictValue();
            }
        }
        return null;
    }

    public List<String> getDictKeys() {
        loadFromDatabase();
        List<BraveDict.DictEntry> entries = braveDict.getDictEntry();
        List<String> keyList = new ArrayList<String>(entries.size());
        for(BraveDict.DictEntry e : entries){
            keyList.add(e.getDictKey());
        }

        Collections.sort(keyList);

        return keyList;

    }

}
